import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// 移除CSS2DRenderer，使用Canvas纹理方案
import { Graph } from './core/Graph.js'
import { Simulator } from './core/Simulator.js'
import { ShaderLoader } from './core/ShaderLoader.js'
import { GeometryGenerator } from './core/GeometryGenerator.js'
import { GPUPicking } from './core/GPUPicking.js'
import { loadGraphDataFromJSON, getDefaultGraphData, validateGraphData, getGraphStatistics } from './data/dataLoader.js'
import { nodeTypeColors, edgeTypeStyles } from './data/sailisiSampleData.js'

/**
 * 3D网络渲染器 - 专为赛力斯知识图谱设计
 */
export default class NetworkRenderer3D {
  constructor(canvas) {
    this.canvas = canvas
    this.scene = null
    this.camera = null
    this.renderer = null
    // 移除labelRenderer，使用Sprite方案
    this.controls = null
    
    // 图数据
    this.graph = new Graph()
    this.simulator = null
    this.gpuPicking = null
    this.shaderLoader = null
    
    // 数据加载相关
    this.graphData = null
    this.dataLoaded = false
    this.dataLoading = false
    this.jsonDataPath = '/exported_graph_data.json'
    
    // 几何体和材质
    this.nodeGeometry = null
    this.edgeGeometry = null
    this.nodeMesh = null
    this.edgeMesh = null
    
    // 状态
    this.isSimulating = false
    this.temperature = 100
    this.kValue = 100
    this.layoutMode = 'force'
    this.showLabels = true
    
    // 高亮状态
    this.selectedNode = null
    this.highlightedNodes = new Set()
    this.highlightedEdges = new Set()
    this.isHighlightMode = false
    
    // 标签相关
    this.nodeLabels = []
    this.labelObjects = []
    
    // 中心文字相关
    this.centerText = null
    this.centerTextMesh = null
    
    // 动画相关
    this.isAnimatingLayout = false
    this.animationStartTime = 0
    this.animationDuration = 2000
    this.currentEasingType = 'easeInOutCubic'
    this.currentPositions = null
    this.targetPositions = null
    this.startPositions = null
    
    // 交互
    this.mouse = new THREE.Vector2()
    this.raycaster = new THREE.Raycaster()
    
    // 回调函数
    this.onDataUpdate = null
    this.onNodeClick = null
    this.onNodeHover = null
    
    // 动画相关
    this.animationId = null
    this.lastTime = performance.now()
    
    // 数据加载状态
    this.isDataLoaded = false
    
    this.bindEvents()
  }

  /**
   * 加载图数据
   * @param {string} jsonPath - JSON文件路径，可选
   */
  async loadGraphData(jsonPath = null) {
    if (this.dataLoading) {
      console.warn('数据正在加载中，请稍候...')
      return false
    }
    
    this.dataLoading = true
    this.dataLoaded = false
    
    try {
      const dataPath = jsonPath || this.jsonDataPath
      console.log(`🔄 开始加载图数据: ${dataPath}`)
      
      // 加载并验证JSON数据（新接口已内置验证）
      this.graphData = await loadGraphDataFromJSON(dataPath)
      
      // 更新图对象（使用标准接口）
      this.graph.setData(this.graphData)
      
      this.dataLoaded = true
      console.log('✅ 图数据加载完成')
      
      return true
    } catch (error) {
      console.error('❌ 加载图数据失败:', error)
      
      // 使用默认数据作为fallback
      console.log('🔄 使用默认数据作为fallback')
      this.graphData = getDefaultGraphData()
      this.graph.setData(this.graphData)
      this.dataLoaded = true
      
      return false
    } finally {
      this.dataLoading = false
    }
  }

  /**
   * 初始化渲染器
   */
  async init() {
    // 先加载数据
    await this.loadGraphData()
    
    this.initRenderer()
    this.initScene()
    this.initCamera()
    this.initControls()
    this.initShaders()
    this.createCenterText()
    
    // 开始动画循环
    this.animate()
  }

  /**
   * 检测WebGL支持
   */
  checkWebGLSupport() {
    try {
      const canvas = document.createElement('canvas')
      const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
      if (!gl) {
        return { supported: false, reason: 'WebGL不被浏览器支持' }
      }
      
      // 检查WebGL扩展
      const debugInfo = gl.getExtension('WEBGL_debug_renderer_info')
      if (debugInfo) {
        const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
        console.log('WebGL渲染器:', renderer)
        
        // 检查是否是软件渲染
        if (renderer && renderer.toLowerCase().includes('software')) {
          return { 
            supported: true, 
            warning: '检测到软件渲染，性能可能受限',
            renderer 
          }
        }
      }
      
      return { supported: true, renderer: debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : 'Unknown' }
    } catch (error) {
      return { supported: false, reason: `WebGL检测失败: ${error.message}` }
    }
  }

  /**
   * 初始化WebGL渲染器
   */
  initRenderer() {
    // 首先检测WebGL支持
    const webglCheck = this.checkWebGLSupport()
    if (!webglCheck.supported) {
      throw new Error(`WebGL不支持: ${webglCheck.reason}`)
    }
    
    if (webglCheck.warning) {
      console.warn(webglCheck.warning)
    }
    
    try {
      // 尝试创建WebGL渲染器，使用更保守的设置
      this.renderer = new THREE.WebGLRenderer({
        canvas: this.canvas,
        antialias: false, // 禁用抗锯齿以减少GPU负载
        alpha: true,
        powerPreference: "high-performance", // 优先使用独立显卡
        failIfMajorPerformanceCaveat: false, // 允许在性能较差的情况下继续
        preserveDrawingBuffer: false, // 不保留绘图缓冲区以节省内存
        premultipliedAlpha: false,
        depth: true,
        stencil: false,
        logarithmicDepthBuffer: false
      })
      
      const rect = this.canvas.getBoundingClientRect()
      this.renderer.setSize(rect.width, rect.height)
      
      // 使用较低的像素比以减少GPU负载
      const pixelRatio = Math.min(window.devicePixelRatio, 2)
      this.renderer.setPixelRatio(pixelRatio)
      this.renderer.setClearColor(0x0a0a0a, 1)
      
      // 启用深度测试
      this.renderer.depthTest = true
      this.renderer.depthWrite = true
      
      // 添加上下文丢失监听器
      this.canvas.addEventListener('webglcontextlost', this.handleContextLost.bind(this), false)
      this.canvas.addEventListener('webglcontextrestored', this.handleContextRestored.bind(this), false)
      
      console.log('WebGL渲染器初始化成功，使用渲染器:', webglCheck.renderer)
      
    } catch (error) {
      console.error('WebGL渲染器创建失败:', error)
      throw new Error(`WebGL渲染器创建失败: ${error.message}`)
    }
  }

  /**
   * 处理WebGL上下文丢失
   */
  handleContextLost(event) {
    console.warn('WebGL上下文丢失')
    event.preventDefault()
    
    // 停止动画循环
    if (this.animationId) {
      cancelAnimationFrame(this.animationId)
      this.animationId = null
    }
    
    // 通知用户
    if (this.onError) {
      this.onError('WebGL上下文丢失，请刷新页面重试')
    }
  }

  /**
   * 处理WebGL上下文恢复
   */
  handleContextRestored(event) {
    console.log('WebGL上下文已恢复')
    
    try {
      // 重新初始化场景
      this.initScene()
      this.initCamera()
      this.initLights()
      
      // 重新加载数据
      if (this.isDataLoaded) {
        this.loadGraphData(this.currentGraphData)
      }
      
      // 重启动画循环
      this.animate()
      
    } catch (error) {
      console.error('WebGL上下文恢复失败:', error)
      if (this.onError) {
        this.onError('WebGL上下文恢复失败，请刷新页面')
      }
    }
  }

  /**
   * 初始化场景
   */
  initScene() {
    this.scene = new THREE.Scene()
    
    // 添加环境光
    const ambientLight = new THREE.AmbientLight(0x404040, 0.4)
    this.scene.add(ambientLight)
    
    // 添加方向光
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
    directionalLight.position.set(1, 1, 1)
    this.scene.add(directionalLight)
    
    // 添加点光源
    const pointLight = new THREE.PointLight(0x4ecdc4, 0.5, 2000)
    pointLight.position.set(0, 500, 0)
    this.scene.add(pointLight)
  }

  /**
   * 创建中心文字
   */
  createCenterText() {
    // 创建文字几何体
    const canvas = document.createElement('canvas')
    const context = canvas.getContext('2d')
    canvas.width = 102400
    canvas.height = 25600
    
    // 设置文字样式
    context.fillStyle = 'rgba(0, 0, 0, 0.8)'
    context.fillRect(0, 0, canvas.width, canvas.height)
    
    context.fillStyle = '#ffffff'
    context.font = 'bold 6400px Arial, sans-serif'
    context.textAlign = 'center'
    context.textBaseline = 'middle'
    
    // 绘制文字
    context.fillText('赛力斯智能问答知识图谱', canvas.width / 2, canvas.height / 2)
    
    // 创建纹理
    const texture = new THREE.CanvasTexture(canvas)
    texture.needsUpdate = true
    
    // 创建材质
    const material = new THREE.MeshBasicMaterial({
      map: texture,
      transparent: true,
      alphaTest: 0.1
    })
    
    // 创建几何体 - 扩大20倍
    const geometry = new THREE.PlaneGeometry(480*1.5, 120*1.5)
    
    // 创建网格
    this.centerTextMesh = new THREE.Mesh(geometry, material)
    this.centerTextMesh.position.set(0, 0, 0.1) // 稍微向前一点，避免z-fighting
    this.centerTextMesh.visible = false // 默认隐藏
    
    // 添加到场景
    this.scene.add(this.centerTextMesh)
  }

  /**
   * 初始化相机
   */
  initCamera() {
    const rect = this.canvas.getBoundingClientRect()
    this.camera = new THREE.PerspectiveCamera(
      75,
      rect.width / rect.height,
      1,
      10000
    )
    
    this.camera.position.set(800, 600, 800)
    this.camera.lookAt(0, 0, 0)
  }

  /**
   * 初始化控制器
   */
  initControls() {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    
    this.controls.enableDamping = true
    this.controls.dampingFactor = 0.08
    this.controls.enableZoom = true
    this.controls.enableRotate = true
    this.controls.enablePan = true
    
    this.controls.minDistance = 50
    this.controls.maxDistance = 3000
    this.controls.zoomSpeed = 1.2
    this.controls.rotateSpeed = 1.0
    this.controls.panSpeed = 0.8
    
    this.controls.maxPolarAngle = Math.PI
    this.controls.minPolarAngle = 0
    this.controls.target.set(0, 0, 0)
    
    this.controls.autoRotate = false
    this.controls.autoRotateSpeed = 1.0
  }

  /**
   * 初始化着色器
   */
  initShaders() {
    this.shaderLoader = new ShaderLoader()
    this.shaderLoader.onShadersLoaded = () => {
      this.onShadersReady()
    }
    this.shaderLoader.loadShaders()
  }

  /**
   * 着色器加载完成回调
   */
  onShadersReady() {
    console.log(`[${new Date().toLocaleTimeString()}] 着色器加载完成`)
  }


  /**
   * 处理图数据
   */
  processGraphData() {
    // 计算统计信息
    const stats = this.graph.getStats()
    
    if (this.onDataUpdate) {
      this.onDataUpdate({
        nodeCount: stats.nodeCount,
        edgeCount: stats.edgeCount,
        totalDataPoints: stats.totalDataPoints
      })
    }
  }

  /**
   * 创建几何体
   */
  createGeometry() {
    const generator = new GeometryGenerator(this.graph)
    const { nodeGeometry, edgeGeometry } = generator.generate()
    
    this.nodeGeometry = nodeGeometry
    this.edgeGeometry = edgeGeometry
    
    console.log('[createGeometry] 几何体创建完成')
    
    // 创建材质和网格
    this.createMaterials()
    this.createMeshes()
    
    // 确保颜色正确应用
    this.applyNodeTypeColors()
    console.log('[createGeometry] 节点颜色已应用')
  }

  /**
   * 应用节点类型颜色
   */
  applyNodeTypeColors() {
    if (!this.nodeGeometry) return

    const colorAttribute = this.nodeGeometry.attributes.color
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    
    nodes.forEach((node, index) => {
      // 优先使用节点的 color 属性，如果没有则使用类型颜色
      let color = node?.data?.[0]?.color || node?.color
      
      if (!color) {
        // 如果节点没有颜色属性，使用类型颜色作为备用
        const nodeType = node?.data?.[0]?.type || node?.type || 'default'
        color = nodeTypeColors[nodeType] || '#ffffff'
      }
      
      // 确保 color 是字符串类型
      if (typeof color !== 'string') {
        console.warn('[applyNodeTypeColors] 节点颜色不是字符串类型:', color, '节点:', node)
        const nodeType = node?.data?.[0]?.type || node?.type || 'default'
        color = nodeTypeColors[nodeType] || '#ffffff'
      }
      
      // 将十六进制颜色转换为RGB
      const hex = color.replace('#', '')
      const r = parseInt(hex.substr(0, 2), 16) / 255
      const g = parseInt(hex.substr(2, 2), 16) / 255
      const b = parseInt(hex.substr(4, 2), 16) / 255
      
      colorAttribute.array[index * 3] = r
      colorAttribute.array[index * 3 + 1] = g
      colorAttribute.array[index * 3 + 2] = b
    })

    colorAttribute.needsUpdate = true
  }

  /**
   * 应用边的原始颜色（基于节点颜色的渐变）
   */
  applyEdgeOriginalColors() {
    if (!this.edgeGeometry) return

    const colorAttribute = this.edgeGeometry.attributes.color
    const edges = Object.values(this.graph.edges)
    const nodes = this.graph.nodes
    
    // 创建临时的几何体生成器来获取节点颜色
    const geometryGenerator = new GeometryGenerator(this.graph)
    
    edges.forEach((edge, index) => {
      const sourceNode = nodes[edge.source]
      const targetNode = nodes[edge.target]
      
      if (sourceNode && targetNode) {
        // 获取源节点和目标节点的颜色
        const sourceColor = geometryGenerator.getNodeColorRGB(sourceNode)
        const targetColor = geometryGenerator.getNodeColorRGB(targetNode)
        
        // 每条边有2个顶点，每个顶点3个颜色分量
        const startIndex = index * 6
        
        // 源节点颜色（边的起点）
        colorAttribute.array[startIndex] = sourceColor.r
        colorAttribute.array[startIndex + 1] = sourceColor.g
        colorAttribute.array[startIndex + 2] = sourceColor.b
        
        // 目标节点颜色（边的终点）
        colorAttribute.array[startIndex + 3] = targetColor.r
        colorAttribute.array[startIndex + 4] = targetColor.g
        colorAttribute.array[startIndex + 5] = targetColor.b
      }
    })

    colorAttribute.needsUpdate = true
  }

  /**
   * 创建材质
   */
  createMaterials() {
    // 节点材质
    this.nodeMaterial = new THREE.ShaderMaterial({
      vertexShader: `
        attribute vec3 color;
        attribute float size;
        varying vec3 vColor;
        void main() {
          vColor = color;
          vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
          gl_PointSize = size * (300.0 / -mvPosition.z);
          gl_Position = projectionMatrix * mvPosition;
        }
      `,
      fragmentShader: `
        varying vec3 vColor;
        void main() {
          float dist = distance(gl_PointCoord, vec2(0.5));
          if (dist > 0.5) discard;
          float alpha = 1.0 - smoothstep(0.3, 0.5, dist);
          gl_FragColor = vec4(vColor, alpha);
        }
      `,
      transparent: true
    })
    
    // 边材质 - 启用顶点颜色支持渐变
    this.edgeMaterial = new THREE.LineBasicMaterial({
      vertexColors: true,
      transparent: true,
      opacity: 0.2  // 默认透明度，让边不那么突出
    })
  }

  /**
   * 创建网格
   */
  createMeshes() {
    // 创建节点网格
    this.nodeMesh = new THREE.Points(this.nodeGeometry, this.nodeMaterial)
    this.scene.add(this.nodeMesh)
    
    // 创建节点标签
    this.createNodeLabels()
    
    // 创建边网格
    this.edgeMesh = new THREE.LineSegments(this.edgeGeometry, this.edgeMaterial)
    this.scene.add(this.edgeMesh)
  }

  /**
   * 创建节点标签 - 使用Canvas纹理方案
   */
  createNodeLabels() {
    // 清理现有标签
    this.clearNodeLabels()
    
    if (!this.showLabels) return
    
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    const positionAttribute = this.nodeGeometry.attributes.position
    
    nodes.forEach((node, index) => {
      // 获取节点颜色
      const nodeColor = this.getNodeColor(node)
      
      // 根据高亮状态调整文本属性
      let textColor = nodeColor
      let fontSize = 224
      let opacity = 1.0
      let scale = 20
      let fontWeight = 'normal'
      
      if (this.isHighlightMode) {
        if (this.highlightedNodes.has(index)) {
          // 高亮节点：增强显示
          opacity = 1.0
          scale = 28 // 明显放大
          fontWeight = 'bold' // 加粗字体
          // 使用更鲜艳的颜色
          const color = new THREE.Color(nodeColor)
          color.multiplyScalar(1.3) // 增强颜色
          textColor = '#' + color.getHexString()
        } else {
          // 非高亮节点：明显变暗变小
          opacity = 0.2
          scale = 12 // 明显缩小
          textColor = '#888888' // 更深的灰色
        }
        
        // 特别处理选中节点
        if (this.selectedNode !== null && index === this.selectedNode) {
          opacity = 1.0
          scale = 35 // 最大
          textColor = '#FFD700' // 金色突出
          fontWeight = 'bold'
        }
      }
      
      // 创建文字纹理
      const textData = this.createTextTexture(node.name, textColor, fontSize, fontWeight)
      
      // 创建材质
      const material = new THREE.SpriteMaterial({ 
        map: textData.texture,
        transparent: true,
        opacity: opacity
      })
      
      // 创建精灵
      const sprite = new THREE.Sprite(material)
      
      // 设置标签位置（稍微偏移以避免与节点重叠）
      const x = positionAttribute.array[index * 3] - 50 // 向左偏移50单位
      const y = positionAttribute.array[index * 3 + 1]     // 垂直居中
      const z = positionAttribute.array[index * 3 + 2]
      
      sprite.position.set(x, y, z)
      
      // 设置精灵大小（根据高亮状态调整）
      sprite.scale.set(textData.width / 4 * scale / 100, textData.height / 4 * scale / 100, 1)
      
      // 添加到场景
      this.scene.add(sprite)
      
      // 保存引用
      this.labelObjects.push(sprite)
    })
  }

  /**
   * 清理节点标签
   */
  clearNodeLabels() {
    this.labelObjects.forEach(labelObject => {
      // 清理纹理资源
      if (labelObject.material && labelObject.material.map) {
        labelObject.material.map.dispose()
      }
      if (labelObject.material) {
        labelObject.material.dispose()
      }
      this.scene.remove(labelObject)
    })
    this.labelObjects = []
    this.nodeLabels = []
  }

  /**
   * 更新节点标签位置
   */
  updateNodeLabelsPosition() {
    if (!this.showLabels || !this.nodeGeometry || this.labelObjects.length === 0) return
    
    const positionAttribute = this.nodeGeometry.attributes.position
    
    this.labelObjects.forEach((labelObject, index) => {
      const x = positionAttribute.array[index * 3] - 50 // 向左偏移50单位
      const y = positionAttribute.array[index * 3 + 1]     // 垂直居中
      const z = positionAttribute.array[index * 3 + 2]
      
      labelObject.position.set(x, y, z)
    })
  }

  /**
   * 获取节点颜色
   */
  getNodeColor(node) {
    const nodeData = this.graph.nodes[node.name]
    
    // 优先使用节点的 color 属性，如果没有则使用类型颜色
    let color = nodeData?.data?.[0]?.color || nodeData?.color
    
    if (!color) {
      // 如果节点没有颜色属性，使用类型颜色作为备用
      const nodeType = nodeData?.data?.[0]?.type || nodeData?.type || 'default'
      color = nodeTypeColors[nodeType] || '#ffffff'
    }
    
    // 确保 color 是字符串类型
    if (typeof color !== 'string') {
      console.warn('[getNodeColor] 节点颜色不是字符串类型:', color, '节点:', nodeData)
      const nodeType = nodeData?.data?.[0]?.type || nodeData?.type || 'default'
      color = nodeTypeColors[nodeType] || '#ffffff'
    }
    
    return color
  }

  /**
   * 创建文字纹理
   */
  createTextTexture(text, color = '#ffffff', fontSize = 32, fontWeight = 'normal') {
    const canvas = document.createElement('canvas')
    const context = canvas.getContext('2d')
    
    // 设置字体（包含字体粗细）
    context.font = `${fontWeight} ${fontSize}px Arial, sans-serif`
    
    // 计算文字尺寸
    const metrics = context.measureText(text)
    const textWidth = metrics.width
    const textHeight = fontSize
    
    // 设置画布尺寸（添加padding）
    const padding = 12
    canvas.width = textWidth + padding * 2
    canvas.height = textHeight + padding * 2
    
    // 重新设置字体（因为改变canvas大小会重置context）
    context.font = `${fontWeight} ${fontSize}px Arial, sans-serif`
    context.textAlign = 'center'
    context.textBaseline = 'middle'
    
    // 清除背景（保持透明）
    context.clearRect(0, 0, canvas.width, canvas.height)
    
    // 绘制文字
    context.fillStyle = color
    context.fillText(text, canvas.width / 2, canvas.height / 2)
    
    // 创建纹理
    const texture = new THREE.CanvasTexture(canvas)
    texture.needsUpdate = true
    
    return {
      texture,
      width: canvas.width,
      height: canvas.height
    }
  }

  /**
   * 将十六进制颜色转换为rgba格式
   */
  hexToRgba(hex, alpha = 1) {
    // 移除#号
    hex = hex.replace('#', '')
    
    // 解析RGB值
    const r = parseInt(hex.substring(0, 2), 16)
    const g = parseInt(hex.substring(2, 4), 16)
    const b = parseInt(hex.substring(4, 6), 16)
    
    return `rgba(${r}, ${g}, ${b}, ${alpha})`
  }

  /**
   * 切换标签显示
   */
  toggleLabels(show) {
    this.showLabels = show
    
    if (show && this.nodeGeometry) {
      this.createNodeLabels()
    } else {
      this.clearNodeLabels()
    }
  }

  /**
   * 初始化模拟器
   */
  initSimulator() {
    // 防止重复初始化
    if (this.simulator) {
      console.log('模拟器已存在，跳过重复初始化')
      return
    }
    
    this.simulator = new Simulator(this.renderer, this.graph)
    this.simulator.init()
    
    // 立即更新几何体位置以匹配模拟器的初始位置
    this.syncGeometryWithSimulator()
  }

  /**
   * 同步几何体与模拟器位置
   */
  syncGeometryWithSimulator() {
    if (this.simulator && this.nodeGeometry && this.edgeGeometry) {
      const positions = this.simulator.getPositions()
      if (positions) {
        const geometryGenerator = new GeometryGenerator(this.graph)
        geometryGenerator.updateNodePositions(this.nodeGeometry, positions)
        geometryGenerator.updateEdgePositions(this.edgeGeometry, positions)
        
        // 同步标签位置
        this.updateNodeLabelsPosition()
        
        console.log('几何体位置已与模拟器同步')
      }
    }
  }

  /**
   * 动画循环
   */
  animate() {
    this.animationId = requestAnimationFrame(() => this.animate())
    
    const currentTime = performance.now()
    const deltaTime = (currentTime - this.lastTime) / 1000
    this.lastTime = currentTime
    
    this.update(deltaTime)
    this.render()
  }

  /**
   * 更新逻辑
   */
  update(deltaTime) {
    if (this.controls) {
      this.controls.update()
    }
    
    if (this.isAnimatingLayout) {
      this.updateLayoutAnimation()
    }
    
    if (this.isSimulating && this.simulator && !this.isAnimatingLayout) {
      this.temperature *= 0.99
      this.simulator.update(deltaTime, this.temperature)
      
      const positions = this.simulator.getPositions()
      if (positions && this.nodeGeometry && this.edgeGeometry) {
        const geometryGenerator = new GeometryGenerator(this.graph)
        geometryGenerator.updateNodePositions(this.nodeGeometry, positions)
        geometryGenerator.updateEdgePositions(this.edgeGeometry, positions)
        
        // 同步标签位置
        this.updateNodeLabelsPosition()
      }
      
      if (this.onDataUpdate) {
        this.onDataUpdate({ temperature: this.temperature })
      }
    }
  }

  /**
   * 更新布局动画
   */
  updateLayoutAnimation() {
    if (!this.isAnimatingLayout || !this.startPositions || !this.targetPositions) return
    
    const currentTime = performance.now()
    const elapsed = currentTime - this.animationStartTime
    const progress = Math.min(elapsed / this.animationDuration, 1)
    
    const easedProgress = this[this.currentEasingType](progress)
    
    const positionAttribute = this.nodeGeometry.attributes.position
    
    for (let i = 0; i < positionAttribute.count * 3; i++) {
      const startPos = this.startPositions[i]
      const targetPos = this.targetPositions[i]
      const currentPos = startPos + (targetPos - startPos) * easedProgress
      
      positionAttribute.array[i] = currentPos
    }
    
    positionAttribute.needsUpdate = true
    
    // 同步标签位置
    this.updateNodeLabelsPosition()
    
    if (this.edgeGeometry) {
      const geometryGenerator = new GeometryGenerator(this.graph)
      geometryGenerator.updateEdgePositions(this.edgeGeometry, positionAttribute.array)
    }
    
    // 更新文字透明度动画
    if (this.centerTextMaterial) {
      const currentOpacity = this.centerTextStartOpacity + (this.centerTextTargetOpacity - this.centerTextStartOpacity) * easedProgress
      this.centerTextMaterial.opacity = currentOpacity
    }
    
    if (progress >= 1) {
      this.isAnimatingLayout = false
      console.log('布局动画完成')
      
      // 确保中心文字在动画完成后正确显示
      if (this.centerTextMesh) {
        this.centerTextMesh.visible = (this.layoutMode === 'circle')
      }
      
      if (this.layoutMode === 'force') {
        this.temperature = 100
        if (this.simulator) {
          // 从当前几何体位置同步模拟器位置，而不是重置
          const positionAttribute = this.nodeGeometry.attributes.position
          this.simulator.syncPositionsFromGeometry(positionAttribute.array)
          this.simulator.setLayoutMode('force')
          console.log('已同步几何体位置到模拟器')
        }
        // 启动力导向模拟
        this.setSimulation(true)
      } else {
        // 非力导向布局完成后，保持静态状态
        if (this.simulator) {
          this.simulator.setLayoutMode('static')
          console.log(`${this.layoutMode} 布局完成，保持静态状态`)
        }
        // 停止力导向模拟
        this.setSimulation(false)
      }
    }
  }

  /**
   * 渲染
   */
  render() {
    this.renderer.render(this.scene, this.camera)
    // 标签现在使用Sprite，会在主渲染中自动渲染
  }

  /**
   * 缓动函数
   */
  easeInOutCubic(t) {
    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2
  }

  easeOutElastic(t) {
    const c4 = (2 * Math.PI) / 3
    return t === 0
      ? 0
      : t === 1
      ? 1
      : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1
  }

  easeInOutQuart(t) {
    return t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2
  }

  /**
   * 设置布局模式
   */
  setLayoutMode(mode) {
    this.layoutMode = mode
    
    // 控制中心文字的显示/隐藏
    if (this.centerTextMesh) {
      this.centerTextMesh.visible = (mode === 'circle')
    }
    
    this.animateToLayout(mode)
  }

  /**
   * 动画到新布局
   */
  animateToLayout(layoutType) {
    if (!this.nodeGeometry) return
    
    const positionAttribute = this.nodeGeometry.attributes.position
    const nodeCount = positionAttribute.count
    
    this.startPositions = new Float32Array(positionAttribute.array)
    this.targetPositions = new Float32Array(positionAttribute.count * 3)
    
    this.calculateTargetPositions(layoutType, this.targetPositions, nodeCount)
    
    this.isAnimatingLayout = true
    this.animationStartTime = performance.now()
    
    // 在动画期间暂停力导向模拟，避免位置冲突
    if (this.simulator) {
      this.simulator.setLayoutMode('paused')
    }
    
    console.log(`开始布局动画: ${layoutType}`)
  }

  /**
   * 计算目标位置
   */
  calculateTargetPositions(layoutType, targetPositions, nodeCount) {
    switch (layoutType) {
      case 'circle':
        this.calculateCirclePositions(targetPositions, nodeCount)
        break
      case 'sphere':
        this.calculateSpherePositions(targetPositions, nodeCount)
        break
      case 'spiral':
        this.calculateSpiralPositions(targetPositions, nodeCount)
        break
      case 'grid':
        this.calculateGridPositions(targetPositions, nodeCount)
        break
      case 'force':
        this.calculateRandomPositions(targetPositions, nodeCount)
        break
      default:
        this.calculateRandomPositions(targetPositions, nodeCount)
        break
    }
  }

  /**
   * 圆形布局
   */
  calculateCirclePositions(positions, nodeCount) {
    const radius = 600
    for (let i = 0; i < nodeCount; i++) {
      const angle = (i / nodeCount) * Math.PI * 2
      positions[i * 3] = Math.cos(angle) * radius
      positions[i * 3 + 1] = Math.sin(angle) * radius
      positions[i * 3 + 2] = 0
    }
  }

  /**
   * 球形布局
   */
  calculateSpherePositions(positions, nodeCount) {
    const radius = 500
    for (let i = 0; i < nodeCount; i++) {
      const y = 1 - (i / (nodeCount - 1)) * 2
      const radiusAtY = Math.sqrt(1 - y * y)
      const theta = (Math.PI * (3 - Math.sqrt(5))) * i
      
      const x = Math.cos(theta) * radiusAtY
      const z = Math.sin(theta) * radiusAtY
      
      positions[i * 3] = x * radius
      positions[i * 3 + 1] = y * radius
      positions[i * 3 + 2] = z * radius
    }
  }

  /**
   * 螺旋线布局
   */
  calculateSpiralPositions(positions, nodeCount) {
    const maxRadius = 500
    
    for (let i = 0; i < nodeCount; i++) {
      const t = i / nodeCount
      const angle = t * Math.PI * 10 // 10圈螺旋
      const radius = t * maxRadius
      
      positions[i * 3] = Math.cos(angle) * radius
      positions[i * 3 + 1] = Math.sin(angle) * radius
      positions[i * 3 + 2] = (t - 0.5) * 1600 // Z轴变化
    }
  }

  /**
   * 网格布局
   */
  calculateGridPositions(positions, nodeCount) {
    const gridSize = Math.ceil(Math.cbrt(nodeCount))
    const spacing = 120
    
    for (let i = 0; i < nodeCount; i++) {
      const x = i % gridSize
      const y = Math.floor(i / gridSize) % gridSize
      const z = Math.floor(i / (gridSize * gridSize))
      
      positions[i * 3] = (x - gridSize / 2) * spacing
      positions[i * 3 + 1] = (y - gridSize / 2) * spacing
      positions[i * 3 + 2] = (z - gridSize / 2) * spacing
    }
  }

  /**
   * 随机布局
   */
  calculateRandomPositions(positions, nodeCount) {
    const range = 800
    for (let i = 0; i < nodeCount; i++) {
      positions[i * 3] = (Math.random() - 0.5) * range
      positions[i * 3 + 1] = (Math.random() - 0.5) * range
      positions[i * 3 + 2] = (Math.random() - 0.5) * range
    }
  }

  /**
   * 设置模拟状态
   */
  setSimulation(enabled) {
    this.isSimulating = enabled
  }

  /**
   * 重置布局
   */
  resetLayout() {
    this.temperature = 100
    if (this.simulator) {
      this.simulator.reset()
      // 重置后立即同步几何体位置
      setTimeout(() => {
        this.syncGeometryWithSimulator()
      }, 50)
    }
  }

  /**
   * 设置自动旋转
   */
  setAutoRotate(enabled, speed = 1.0) {
    if (this.controls) {
      this.controls.autoRotate = enabled
      this.controls.autoRotateSpeed = speed
    }
  }

  /**
   * 重置相机
   */
  resetCamera() {
    if (this.camera && this.controls) {
      this.camera.position.set(800, 600, 800)
      this.controls.target.set(0, 0, 0)
      this.controls.update()
    }
  }

  /**
   * 事件绑定
   */
  bindEvents() {
    window.addEventListener('resize', () => this.onWindowResize())
    this.canvas.addEventListener('click', (event) => this.onMouseClick(event))
    this.canvas.addEventListener('dblclick', (event) => this.onMouseDoubleClick(event))
    this.canvas.addEventListener('mousemove', (event) => this.onMouseMove(event))
  }

  /**
   * 窗口大小改变处理
   */
  onWindowResize() {
    if (this.camera && this.renderer) {
      const rect = this.canvas.getBoundingClientRect()
      this.camera.aspect = rect.width / rect.height
      this.camera.updateProjectionMatrix()
      this.renderer.setSize(rect.width, rect.height)
      
      // 标签现在使用Sprite，不需要单独的渲染器
    }
  }

  /**
   * 鼠标点击处理
   */
  onMouseClick(event) {
    const rect = this.canvas.getBoundingClientRect()
    this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
    this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
    
    this.raycaster.setFromCamera(this.mouse, this.camera)
    
    let nodeClicked = false
    
    if (this.nodeMesh) {
      const intersects = this.raycaster.intersectObject(this.nodeMesh)
      if (intersects.length > 0) {
        const nodeIndex = intersects[0].index
        this.selectNode(nodeIndex)
        nodeClicked = true
        
        if (this.onNodeClick) {
          this.onNodeClick(nodeIndex, this.getNodeInfo(nodeIndex))
        }
      }
    }
    
    // 单击空白不再清除高亮，改为双击空白清除
  }

  /**
   * 鼠标双击处理
   */
  onMouseDoubleClick(event) {
    const rect = this.canvas.getBoundingClientRect()
    this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
    this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
    
    this.raycaster.setFromCamera(this.mouse, this.camera)
    
    let nodeClicked = false
    
    if (this.nodeMesh) {
      const intersects = this.raycaster.intersectObject(this.nodeMesh)
      if (intersects.length > 0) {
        nodeClicked = true
      }
    }
    
    // 双击空白区域时清除高亮
    if (!nodeClicked && this.isHighlightMode) {
      this.clearHighlight()
    }
  }

  /**
   * 鼠标移动处理
   */
  onMouseMove(event) {
    // 可以在这里实现节点悬停效果
  }

  /**
   * 选择节点
   */
  selectNode(nodeIndex) {
    if (this.selectedNode === nodeIndex && this.isHighlightMode) {
      // 如果点击的是已选中的节点，取消高亮
      this.clearHighlight()
    } else {
      // 选择新节点并高亮
      this.selectedNode = nodeIndex
      this.highlightNodeAndNeighbors(nodeIndex)
    }
  }

  /**
   * 高亮节点和邻居
   */
  highlightNodeAndNeighbors(nodeIndex) {
    if (!this.nodeGeometry || !this.edgeGeometry) return
    
    // 如果点击的是已选中的节点，则取消高亮（切换功能）
    if (this.selectedNode === nodeIndex && this.isHighlightMode) {
      this.clearHighlight()
      return
    }
    
    this.isHighlightMode = true
    this.selectedNode = nodeIndex
    this.highlightedNodes.clear()
    this.highlightedEdges.clear()
    
    // 获取节点列表
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    const selectedNode = nodes[nodeIndex]
    if (!selectedNode) return
    
    console.log('高亮节点:', selectedNode.name, 'ID:', selectedNode.id)
    
    // 找到所有相关的节点和边
    this.highlightedNodes.add(nodeIndex)
    
    // 遍历所有边，找到与选中节点相关的边和邻居节点
    const edges = Object.values(this.graph.edges)
    let connectedEdges = 0
    console.log('开始查找邻居节点，选中节点ID:', selectedNode.id)
    console.log('总边数:', edges.length)
    
    edges.forEach((edge, edgeIndex) => {
      console.log(`检查边 ${edgeIndex}: source=${edge.source}, target=${edge.target}`)
      // 边的source/target是节点名称(字符串)，需要与selectedNode.name比较
      if (edge.source === selectedNode.name || edge.target === selectedNode.name) {
        connectedEdges++
        this.highlightedEdges.add(edgeIndex)
        console.log(`找到连接边 ${edgeIndex}`)
        
        // 添加邻居节点
        const neighborName = edge.source === selectedNode.name ? edge.target : edge.source
        console.log(`邻居节点名称: ${neighborName}`)
        const neighborIndex = nodes.findIndex(node => node.name === neighborName)
        console.log(`邻居节点索引: ${neighborIndex}`)
        if (neighborIndex !== -1) {
          this.highlightedNodes.add(neighborIndex)
          console.log(`添加邻居节点到高亮集合: ${neighborIndex}, 节点名称: ${nodes[neighborIndex].name}`)
        } else {
          console.log(`警告：未找到邻居节点，名称: ${neighborName}`)
        }
      }
    })
    
    console.log('连接边数量:', connectedEdges, '高亮节点总数:', this.highlightedNodes.size, '高亮边数量:', this.highlightedEdges.size)
    console.log('高亮节点索引:', Array.from(this.highlightedNodes))
    console.log('高亮边索引:', Array.from(this.highlightedEdges))
    
    this.updateHighlightEffect()
  }

  /**
   * 更新高亮效果
   */
  updateHighlightEffect() {
    this.updateNodeHighlight()
    this.updateNodeSize()
    this.updateEdgeHighlight()
    
    // 重新创建文本标签以应用高亮样式
    this.createNodeLabels()
  }

  /**
   * 更新节点大小效果
   */
  updateNodeSize() {
    if (!this.nodeGeometry) return
    
    const sizeAttribute = this.nodeGeometry.attributes.size
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    
    if (this.isHighlightMode) {
      // 恢复原始大小
      nodes.forEach((node, index) => {
        const degree = Object.values(this.graph.edges).filter(edge => 
          edge.source === node.id || edge.target === node.id
        ).length
        const originalSize = Math.max(5, Math.min(20, degree * 2)) * 2
        
        if (this.highlightedNodes.has(index)) {
          // 选中节点和邻居节点：增大
          if (index === this.selectedNode) {
            sizeAttribute.array[index] = originalSize * 1.8 // 选中节点最大
          } else {
            sizeAttribute.array[index] = originalSize * 1.4 // 邻居节点适中增大
          }
        } else {
          // 其他节点：保持原始大小或稍微缩小
          sizeAttribute.array[index] = originalSize * 0.8
        }
      })
    } else {
      // 正常状态：恢复原始大小
      nodes.forEach((node, index) => {
        const degree = Object.values(this.graph.edges).filter(edge => 
          edge.source === node.id || edge.target === node.id
        ).length
        sizeAttribute.array[index] = Math.max(5, Math.min(20, degree * 2)) * 2
      })
    }
    
    sizeAttribute.needsUpdate = true
  }

  /**
   * 更新节点高亮效果
   * 三种状态：
   * 1. 正常状态：原始颜色
   * 2. 激活状态：选中节点和邻居节点保持原色或稍微增强
   * 3. 未激活状态：其他节点变暗
   */
  updateNodeHighlight() {
    if (!this.nodeGeometry) return
    
    const colorAttribute = this.nodeGeometry.attributes.color
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    
    // 重置所有节点颜色到原始类型颜色
    this.applyNodeTypeColors()
    
    if (this.isHighlightMode) {
      console.log('应用节点高亮模式, 高亮节点:', Array.from(this.highlightedNodes))
      
      // 处理未激活状态：变暗所有非高亮节点
      for (let i = 0; i < nodes.length; i++) {
        if (!this.highlightedNodes.has(i)) {
          // 未激活状态：适度变暗，保持可见性
          colorAttribute.array[i * 3] *= 0.25      // 红色分量
          colorAttribute.array[i * 3 + 1] *= 0.25  // 绿色分量
          colorAttribute.array[i * 3 + 2] *= 0.25  // 蓝色分量
          console.log(`节点 ${i} (${nodes[i]?.name}) 变暗`)
        } else {
          console.log(`节点 ${i} (${nodes[i]?.name}) 保持高亮`)
        }
      }
      
      // 处理激活状态：选中节点特别突出
      if (this.selectedNode !== null) {
        // 选中节点：增强亮度但保持原色调
        const selectedIndex = this.selectedNode * 3
        colorAttribute.array[selectedIndex] = Math.min(1.0, colorAttribute.array[selectedIndex] * 2.0)
        colorAttribute.array[selectedIndex + 1] = Math.min(1.0, colorAttribute.array[selectedIndex + 1] * 2.0)
        colorAttribute.array[selectedIndex + 2] = Math.min(1.0, colorAttribute.array[selectedIndex + 2] * 2.0)
      }
      
      // 邻居节点：明显增强，使其突出显示
      this.highlightedNodes.forEach(nodeIndex => {
        if (nodeIndex !== this.selectedNode) {
          // 邻居节点：显著增强亮度
          const neighborIndex = nodeIndex * 3
          colorAttribute.array[neighborIndex] = Math.min(1.0, colorAttribute.array[neighborIndex] * 1.8)
          colorAttribute.array[neighborIndex + 1] = Math.min(1.0, colorAttribute.array[neighborIndex + 1] * 1.8)
          colorAttribute.array[neighborIndex + 2] = Math.min(1.0, colorAttribute.array[neighborIndex + 2] * 1.8)
        }
      })
    }
    
    colorAttribute.needsUpdate = true
  }

  /**
   * 更新边高亮效果
   * 三种状态：
   * 1. 正常状态：原始颜色和透明度
   * 2. 激活状态：相关边突出显示
   * 3. 未激活状态：其他边变暗变透明
   */
  updateEdgeHighlight() {
    if (!this.edgeGeometry) return
    
    const edges = Object.values(this.graph.edges)
    
    if (this.isHighlightMode) {
      console.log('应用边高亮模式, 高亮边:', Array.from(this.highlightedEdges))
      
      // 先恢复所有边的原始颜色
      this.applyEdgeOriginalColors()
      
      const colorAttribute = this.edgeGeometry.attributes.color
      
      // 遍历所有边，设置不同的显示效果
      for (let i = 0; i < edges.length; i++) {
        const isHighlighted = this.highlightedEdges.has(i)
        
        // 每条边有2个顶点，每个顶点3个颜色分量
        const startIndex = i * 6 // 每条边6个值(2顶点 * 3颜色分量)
        
        if (isHighlighted) {
          console.log('高亮边索引:', i)
          // 激活状态：设置为明亮的黄色，使其非常明显
          for (let j = 0; j < 6; j += 3) {
            colorAttribute.array[startIndex + j] = 1.0     // 红色
            colorAttribute.array[startIndex + j + 1] = 1.0 // 绿色
            colorAttribute.array[startIndex + j + 2] = 0.0 // 蓝色 (黄色)
          }
        } else {
          // 未激活状态：基于原始颜色变暗
          for (let j = 0; j < 6; j++) {
            colorAttribute.array[startIndex + j] *= 0.05
          }
        }
      }
      
      colorAttribute.needsUpdate = true
      this.edgeMaterial.opacity = 1.0 // 高亮模式下提高整体透明度
    } else {
      // 正常状态：恢复原始颜色
      this.applyEdgeOriginalColors()
      this.edgeMaterial.opacity = 0.4 // 正常状态的透明度
    }
  }

  /**
   * 清除高亮效果，恢复到正常状态
   */
  clearHighlight() {
    this.isHighlightMode = false
    this.selectedNode = null
    this.highlightedNodes.clear()
    this.highlightedEdges.clear()
    
    // 恢复节点到正常状态
    this.applyNodeTypeColors()
    this.updateNodeSize() // 恢复节点大小
    
    // 恢复边到正常状态
    this.applyEdgeOriginalColors()
    
    // 重新创建文本标签以恢复正常样式
    this.createNodeLabels()
    
    // 恢复边的正常透明度
    this.edgeMaterial.opacity = 0.4
  }

  /**
   * 获取节点信息
   */
  getNodeInfo(nodeIndex) {
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    const node = nodes[nodeIndex]
    if (!node) return null
    
    const nodeData = this.graph.nodes[node.name]
    return {
      id: node.id,
      name: node.name,
      type: nodeData?.type,
      category: nodeData?.category,
      degree: node.getDegree(),
      data: node.data
    }
  }

  /**
   * 根据类型高亮节点
   * @param {Array} types - 要高亮的节点类型数组
   */
  highlightNodesByType(types) {
    if (!this.nodeGeometry || !types || types.length === 0) return
    
    // 设置高亮模式和高亮节点
    this.isHighlightMode = true
    this.highlightedNodes.clear()
    
    const colorAttribute = this.nodeGeometry.attributes.color
    const nodes = Object.values(this.graph.nodes).sort((a, b) => a.id - b.id)
    
    nodes.forEach((node, index) => {
      const nodeType = node?.data?.[0]?.type || node?.type || 'default'
      const shouldHighlight = types.includes(nodeType)
      
      if (shouldHighlight) {
        this.highlightedNodes.add(index)
      }
      
      // 获取节点原始颜色
      const originalColor = this.getNodeColor(node)
      const color = new THREE.Color(originalColor)
      
      if (shouldHighlight) {
        // 高亮：增加亮度和饱和度
        color.multiplyScalar(1.5)
      } else {
        // 暗化：降低亮度
        color.multiplyScalar(0.3)
      }
      
      colorAttribute.array[index * 3] = color.r
      colorAttribute.array[index * 3 + 1] = color.g
      colorAttribute.array[index * 3 + 2] = color.b
    })
    
    colorAttribute.needsUpdate = true
    
    // 同时调整边的透明度
    if (this.edgeMaterial) {
      this.edgeMaterial.opacity = 0.2
    }
    
    // 重新创建标签以反映高亮状态
    this.createNodeLabels()
  }
  
  /**
   * 清除所有高亮效果
   */
  clearHighlights() {
    // 清除高亮状态
    this.isHighlightMode = false
    this.highlightedNodes.clear()
    this.selectedNode = null
    
    // 恢复节点原始颜色
    this.applyNodeTypeColors()
    
    // 恢复边的正常透明度
    if (this.edgeMaterial) {
      this.edgeMaterial.opacity = 0.4
    }
    
    // 重新创建标签以恢复正常状态
    this.createNodeLabels()
  }

  /**
   * 销毁资源
   */
  dispose() {
    if (this.animationId) {
      cancelAnimationFrame(this.animationId)
    }
    
    if (this.controls) {
      this.controls.dispose()
    }
    
    if (this.renderer) {
      this.renderer.dispose()
    }
    
    if (this.nodeGeometry) {
      this.nodeGeometry.dispose()
    }
    
    if (this.edgeGeometry) {
      this.edgeGeometry.dispose()
    }
    
    window.removeEventListener('resize', this.onWindowResize)
  }
}
